package com.ls.config.satoken;


import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import cn.dev33.satoken.stp.StpUtil;
import com.ls.constant.SystemConstants;
import com.ls.entity.Customer;
import com.ls.entity.SysUser;
import com.ls.enums.RoleEnum;
import com.ls.service.ICustomerService;
import com.ls.service.ISysUserService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import cn.dev33.satoken.stp.StpInterface;

/**
 * 自定义权限认证接口扩展，Sa-Token 将从此实现类获取每个账号拥有的权限码
 * 不再需要权限表，但是需要权限类保存所有的权限，例如 user.add ,customer.delete 。如果有新增的接口，那么这个类也需要对应的新增
 * 不再需要角色表，但是需要角色枚举类
 * 需要角色对应权限 map<RoleEnum,List<String>>
 * 管理员表 sys_user 保留 增加一个 role_id 字段 C端用户表 customer 增加一个 role_id 字段
 * 删除角色表 sys_role ，不支持多角色，如果有多角色的话，就新开一个角色
 * 暂时前端自行判断 删除菜单表 sys_menu ，增加一个菜单枚举类， 增加一个菜单对应对应页面 map<MenuEnum> MenuEnum 里面应该有序号 单个 menuEnum 对应多个页面 page ,Page  也有序号方便展示
 * @author pengyu
 * @since 2024-06-27
 */
@Component	// 打开此注解，保证此类被springboot扫描，即可完成sa-token的自定义权限验证扩展
@AllArgsConstructor
@Slf4j
public class StpInterfaceImpl implements StpInterface {
    @Lazy
    private final ISysUserService userService;
    @Lazy
    private final ICustomerService customerService;
    @Autowired
    public StpInterfaceImpl(@Lazy ICustomerService customerService,ISysUserService userService) {
        this.customerService = customerService;
        this.userService = userService;
    }

    /**
     * 返回一个账号所拥有的权限码集合
     */
    @Override
    public List<String> getPermissionList(Object loginId, String loginType) {
        log.info("getPermissionList param：{},{}",loginId,loginType);
        if(StringUtils.isBlank(loginType)){
            log.error("loginType 不能为空");
            return new ArrayList<>();
        }
        Long roleId;
        switch (loginType){
            case SystemConstants.PC:
                SysUser user = userService.getById((Long)loginId);
                if(user == null){
                    log.error("loginId 在user表不存在:"+ loginId);
                    return new ArrayList<>();
                }
                roleId = user.getRoleId();
                break;
            case SystemConstants.APP:
                Customer customer = customerService.getById((Long)loginId);
                if(customer == null){
                    log.error("loginId 在customer表不存在:"+ loginId);
                    return new ArrayList<>();
                }
                roleId = customer.getRoleId();
                break;
            default:
                return new ArrayList<>();
        }
        RoleEnum roleEnum = RoleEnum.getRoleEnum(roleId);
        if(roleEnum == null){
            log.error("loginId 对应的roleId 在系统中不存在:{},{}",loginId,roleId);
            return new ArrayList<>();
        }
        List<String> permissionList = new ArrayList<String>();
        switch (roleEnum){
            case ADMIN:
                // TODO 权限定好后回来补充
                break;
            case STAFF:
                // TODO 权限定好后回来补充
                break;
            case MEMBER:
                // TODO 权限定好后回来补充
                break;
            case COMMON:
                // TODO 权限定好后回来补充
                break;
            default:
                return new ArrayList<>();
        }
        return permissionList;
        // 本list仅做模拟，实际项目中要根据具体业务逻辑来查询权限
//        List<String> list = new ArrayList<String>();
//        list.add("101");
//        list.add("user.add");
//        list.add("user.update");
//        list.add("user.get");
//        // list.add("user.delete");
//        list.add("art.*");

//        list.add("user.*");
//        return list;
    }

    /**
     * 返回一个账号所拥有的角色标识集合
     */
    @Override
    public List<String> getRoleList(Object loginId, String loginType) {
        //这里的loginType 始终是 "login" 如果要改，就只能加入两个新类（StpUserUtil 和 StpCustomerUtil），然后新加注解，就太复杂了
        log.info("getRoleList param：{},{}",loginId,loginType);
        if(StringUtils.isBlank(loginType)){
            log.error("loginType 不能为空");
            return new ArrayList<>();
        }
        String loginDevice = StpUtil.getLoginDevice();
        Long roleId;
        switch (loginDevice){
            case SystemConstants.PC:
                SysUser user = userService.getById(Long.parseLong((String) loginId));
                if(user == null){
                    log.error("loginId 在user表不存在:"+ loginId);
                    return new ArrayList<>();
                }
                roleId = user.getRoleId();
                break;
            case SystemConstants.APP:
                Customer customer = customerService.getById(Long.parseLong((String) loginId));
                if(customer == null){
                    log.error("loginId 在customer表不存在:"+ loginId);
                    return new ArrayList<>();
                }
                roleId = customer.getRoleId();
                break;
            default:
                return new ArrayList<>();
        }
        RoleEnum roleEnum = RoleEnum.getRoleEnum(roleId);
        if(roleEnum == null){
            log.error("loginId 对应的roleId 在系统重不存在:{},{}",loginId,roleId);
            return new ArrayList<>();
        }
//        List<String> roleNameList = new ArrayList<>();
//        roleNameList.add(roleEnum.roleName);
        List<String> roleNameList = Stream.of(roleEnum.roleName).collect(Collectors.toList());
        return roleNameList;

        // 本list仅做模拟，实际项目中要根据具体业务逻辑来查询角色
//        List<String> list = new ArrayList<String>();
//        list.add("admin");
//        list.add("super-admin");
//        return list;
    }

}
